import os
import pickle
from Cliente import *
from Veiculo import *
from Multa import *
from Locacao import *
from Tempo import *
tempo = tempo()
class manipulador_de_dados:
    #funcao que gera uma lista com os dados de um arquivo
    def carregar_lista_arquivo(self,nome_arquivo):
        arquivo = open(nome_arquivo)
        lista = pickle.load(arquivo)
        arquivo.close()
        return lista

    #funcao que descarrega uma lista de objetos em um arquivo
    def descarregar_dados_arquivo(self,nome_arquivo,objeto,lista_referente):
        #atualiza a lista em memoria antes de salvar o arquivo com o novo objeto
        lista_referente=self.carregar_lista_arquivo(nome_arquivo) 
        lista_referente.append(objeto)
        arquivo = open(nome_arquivo,"w")
        pickle.dump(lista_referente,arquivo)
        arquivo.close()

    ##joga uma lista em um arquivo qualquer independente de se inserir um objeto novo na lista
    def descarregar_lista_arquivo(self,nome_arquivo,lista_referente):
        #atualiza a lista em memoria antes de salvar o arquivo com o novo objeto
        arquivo = open(nome_arquivo,"w")
        pickle.dump(lista_referente,arquivo)
        arquivo.close()
    
    ##verifica se existe cpf em uma lista de pessoas
    def existe_cpf(self,obj,lista):
        existe= False
        for i in lista:
            if i.GetCpf() == obj.GetCpf():
                existe = True
                break
        return existe

    ##verifica se existe cpf em uma lista de pessoas
    def existe_nome(self,nome,lista):
        existe= False
        for i in lista:
            if i.GetNome() == nome:
                existe = True
                break
        return existe
    

    #verifica se existe placa em uma lista de veiculos
    def existe_placa(self,obj,lista):
        existe= False
        for i in lista:
            if i.GetPlaca() == obj.GetPlaca():
                existe = True
                break
        return existe
		
    #verifica se existe placa em uma lista de veiculos
    def existe_placa2(self,obj,lista):
        existe= False
        for i in lista:
            if i.GetPlaca() == obj.GetplacaDoVeiculo():
                existe = True
                break
        return existe
	
    #verifica se existe placa em uma lista de veiculos
    def existe_locacao(self,placa,lista):
        existe= False
        if len(lista)!=0:
            for i in lista:
                if i.GetplacaDoVeiculo() == placa:
                    existe = True
                    break
            return existe
        else:
            return existe
           

    ##insere obj cliente no arquivo cliente        
    def cadastrar_cliente(self):
        obj_Cliente = Cliente()
        lista_clientes=self.carregar_lista_arquivo("cliente.tab") 
        aux=True
        while aux:
            obj_Cliente.SetCpf(raw_input("\nDIGITE UM CPF VALIDO: "))
            auxiliar=self.existe_cpf(obj_Cliente,lista_clientes)
            if auxiliar==False:
                aux=False
            else:
                print "\nCPF JA CADASTRADO!!!!! FAVOR DIGITAR CPF NAO CADASTRADO!\n"

        obj_Cliente.SetNome(raw_input("\nNOME DO CLIENTE: ").upper())    
        obj_Cliente.SetEndereco(raw_input("\nENDERECO DO CLIENTE: ").upper())
        obj_Cliente.SetTelefone(raw_input("\nTELEFONE DO CLIENTE [SEM HIFEM]: ").upper())
        obj_Cliente.SetMatricula(len(lista_clientes))
        obj_Cliente.SetSenha(raw_input("\nSENHA DO CLIENTE: "))
        lista_clientes.append(obj_Cliente)
        self.descarregar_dados_arquivo("cliente.tab",obj_Cliente,lista_clientes)
        print "\nCLIENTE CADASTRADO COM SUCESSO\n"
        
    ##descadastra cliente
    def descadastrar_cliente(self):
        obj_cliente=Cliente()
        lista_clientes=self.carregar_lista_arquivo("cliente.tab")
        aux=True
        while aux:
            obj_cliente.SetCpf(raw_input("\nDIGITE UM CPF VALIDO: "))
            auxiliar = self.existe_cpf(obj_cliente,lista_clientes)
            if auxiliar == True:
                aux = False
        for p,i in enumerate(lista_clientes):
            if i.GetCpf()==obj_cliente.GetCpf():
                del lista_clientes[p]
                self.descarregar_lista_arquivo("cliente.tab",lista_clientes)
        print "CLIENTE DESCADASTRADO.\n "
    
    def detalhar_cliente(self,nome):
        obj_Cliente = Cliente();
        lista_clientes=self.carregar_lista_arquivo("cliente.tab")
        obj_Cliente.SetNome(nome)
        #FAZ O DETALHAMENTO DO CLIENTE PESQUISADO.
        for p,i in enumerate(lista_clientes):
            if i.GetNome()==obj_Cliente.GetNome():
                obj_Cliente.SetMatricula(i.GetMatricula()),
                obj_Cliente.SetEndereco(i.GetEndereco()),
                obj_Cliente.SetNome(i.GetNome())
                obj_Cliente.SetTelefone(i.GetTelefone()),
                obj_Cliente.SetCpf(i.GetCpf()),
                obj_Cliente.SetSenha(i.GetSenha())
                return obj_Cliente
            
    ##insere obj veiculo no arquivo veiculo
    def cadastrar_veiculo(self):
        obj_veiculo=Veiculo()
        lista_veiculos=self.carregar_lista_arquivo("veiculo.tab")
        aux=True
        while aux:
            obj_veiculo.SetPlaca(raw_input("\nDIGITE A PLACA DO CARRO: "))
            auxiliar = self.existe_placa(obj_veiculo,lista_veiculos)
            if auxiliar == False:
                aux = False
            else:
                print "\nPLACA JA CADASTRADA!!!!! FAVOR DIGITAR PLACA NAO CADASTRADA!\n"
                
        obj_veiculo.SetModelo(raw_input("\nMODELO DO VEICULO: ").upper())
        obj_veiculo.SetKm(int(raw_input("\nQUILOMETRAGEM DO VEICULO: ")))
        obj_veiculo.SetDiariaDaLocacao(int(raw_input("\nDIGITE A DIARIA DO VEICULO A SER PAGA: ")))
        obj_veiculo.SetKmDeManutencao((obj_veiculo.GetKm())+5000)
        obj_veiculo.SetAtivo("ativo")   
        lista_veiculos.append(obj_veiculo)
        self.descarregar_dados_arquivo("veiculo.tab",obj_veiculo,lista_veiculos)
        print  "\nVEICULO CADASTRADO COM SUCESSO\n "

    ##funcao q descadastra veiculo
    def descadastrar_veiculo(self):
        obj_veiculo=Veiculo()
        lista_veiculos=self.carregar_lista_arquivo("veiculo.tab")
        aux=True
        while aux:
            obj_veiculo.SetPlaca(raw_input("\nDIGITE A PLACA DO CARRO: "))
            auxiliar = self.existe_placa(obj_veiculo,lista_veiculos)
            if auxiliar == True:
                aux = False
        for p,i in enumerate(lista_veiculos):
            if i.GetPlaca()==obj_veiculo.GetPlaca():
                del lista_veiculos[p]
                self.descarregar_lista_arquivo("veiculo.tab",lista_veiculos)
        print "\nVEICULO DESCADASTRADO COM SUCESSO\n"
        
    def detalhar_veiculo(self,placa):
        obj_Veiculo = Veiculo();
        lista_veiculos=self.carregar_lista_arquivo("veiculo.tab")
        obj_Veiculo.SetPlaca(placa)
        #FAZ O DETALHAMENTO DO CLIENTE PESQUISADO.
        for p,i in enumerate(lista_veiculos):
            if i.GetPlaca()==obj_Veiculo.GetPlaca():
                obj_Veiculo.SetPlaca(i.GetPlaca()),
                obj_Veiculo.SetModelo(i.GetModelo()),
                obj_Veiculo.SetKm(i.GetKm()),
                obj_Veiculo.SetKmDeManutencao(i.GetKmDeManutencao()),
                obj_Veiculo.SetDiariaDaLocacao(i.GetDiariaDaLocacao()),
                obj_Veiculo.SetAtivo(i.GetAtivo()),
                obj_Veiculo.ListaDeMultas=i.ListaDeMultas
                return obj_Veiculo

    ##pede as informacoes de multa
    def info_multa(self,obj):
        obj_locacao=obj
        multa=Multa()
        multa.SetplacaDoVeiculo(obj_locacao.GetplacaDoVeiculo())
        multa.SetData(raw_input("\nDIGITE A DATA: "))
        multa.SetHora(raw_input("\nDIGITE A HORA: "))
        multa.SetResponsavel(obj_locacao.GetnomeDoCliente())
        multa.SetValor(raw_input("\nDIGITE O VALOR: "))
        multa.SetAtiva("ativa")
        return multa
   
        
    def cadastrar_multa(self,obj1,obj2):        
        lista_veiculos=self.carregar_lista_arquivo("veiculo.tab")
        aux=True
        while aux: 
            obj_veiculo=obj1
            obj_locacao=obj2
            auxiliar = self.existe_placa(obj_veiculo,lista_veiculos)
            if auxiliar == True:
                aux = False        
        obj_multa=self.info_multa(obj_locacao)
        for i in lista_veiculos:
            if i.GetPlaca()==obj_veiculo.GetPlaca():
                i.ListaDeMultas.append(obj_multa)
                self.descarregar_lista_arquivo("veiculo.tab",lista_veiculos)
            
    def detalhar_multa(self):
        lista_veiculos=self.carregar_lista_arquivo("veiculo.tab")
        aux=True
        while aux: 
            obj_multa=Multa()
            placa=raw_input("\nDIGITE A PLACA DO CARRO: ")
            responsavel=raw_input("\nDIGITE O NOME DO RESPONSAVEL PELA MULTA: ").upper()
            obj_multa.SetplacaDoVeiculo(placa)
            obj_multa.SetResponsavel(responsavel)
            auxiliar = self.existe_placa2(obj_multa,lista_veiculos)
            if auxiliar == True:
                aux = False        
        for i in lista_veiculos:
            if i.GetPlaca()==obj_multa.GetplacaDoVeiculo():
                lista = i.ListaDeMultas
        for p,i in enumerate(lista):
            if i.GetResponsavel()==obj_multa.GetResponsavel():
                obj_multa.SetHora(i.GetHora())
                obj_multa.SetValor(i.GetValor())
                obj_multa.SetResponsavel(i.GetResponsavel())
                obj_multa.SetData(i.GetData())
                obj_multa.SetplacaDoVeiculo(i.GetplacaDoVeiculo())                    
                obj_multa.SetAtiva(i.GetAtiva())        
                return obj_multa


    def mostrar_multa(self,obj):
        obj_multa=obj
        print"==========================================\n";
        print"MULTA ENCONTRADA";
        print"PLACA DO VEICULO: " + str(obj_multa.GetplacaDoVeiculo());
        print"CLIENTE RESPONSAVEL: " + str(obj_multa.GetResponsavel()).upper();
        print"DATA: " + str(obj_multa.GetData());
        print"HORA: " + str(obj_multa.GetHora());
        valor=raw_input("VALOR A SER PAGO: " + str(obj_multa.GetValor()))
        print"==========================================";        
               

    def pagar_multa(self):
        obj_multa=self.detalhar_multa()
        self.mostrar_multa(obj_multa)
        lista_veiculos=self.carregar_lista_arquivo("veiculo.tab")                      
        for i in lista_veiculos:
            if i.GetPlaca()==obj_multa.GetplacaDoVeiculo():
                lista = i.ListaDeMultas
        
        for p,i in enumerate(lista):
            if i.GetResponsavel()==obj_multa.GetResponsavel():
                del lista[p]

        obj_veiculo=self.detalhar_veiculo(obj_multa.GetplacaDoVeiculo())
        obj_veiculo.ListaDeMultas = lista
        self.atualizar_arquivo_veiculo(obj_veiculo,obj_multa.GetplacaDoVeiculo())
                                
    
    def abrirLocacao(self):
        obj_Veiculo = Veiculo()
        objManipulador = manipulador_de_dados()
        lista_clientes=self.carregar_lista_arquivo("cliente.tab")
        lista_veiculos=self.carregar_lista_arquivo("veiculo.tab")
        nome = raw_input("NOME DO CLIENTE: ").upper();
        auxiliar=self.existe_nome(nome,lista_clientes)
        if auxiliar==False:
            print "\nCLIENTE NAO CADASTRADO! \n Cadastrar Cliente...";
            self.cadastrar_cliente();
        obj_Cliente = self.detalhar_cliente(nome)
        if len(lista_veiculos)!=0:
            self.mostrar_carros_disp()
            placa = raw_input("\nDIGITE A PLACA DO VEICULO A SER LOCADO: ");
            obj_Veiculo = self.detalhar_veiculo(placa)
            obj_Locacao = self.info_locacao(obj_Veiculo,obj_Cliente)
            senha=''
            while senha!='zero':
                senha=raw_input("\nCLIENTE, DIGITE A SUA SENHA PARA CONFIRMAR A LOCACAO OU ( ZERO ) PARA CANCELAR:")
                if str(senha)==str(obj_Cliente.GetSenha()):
                    obj_Veiculo.SetAtivo("inativo")
                    self.atualizar_arquivo_locacao(obj_Locacao,placa)
                    self.atualizar_arquivo_veiculo(obj_Veiculo,placa)    
                    print "\nLOCACAO REALIZADA COM SUCESSO"
                    break
                print "Senha invalida"
        else:
            print "Nao ha veiculos disponiveis."    

    def info_locacao(self,obj1,obj2):
        obj_Veiculo = obj1
        obj_Cliente = obj2            
        lista_locacao=self.carregar_lista_arquivo("locacao.tab")    
        locacao=Locacao()
        locacao.SetordemDeLocacao(len(lista_locacao))
        locacao.SetplacaDoVeiculo(obj_Veiculo.GetPlaca());
        locacao.SetnomeDoVendedor(raw_input("\nDIGITE O NOME DO VENDEDOR: ").upper());
        locacao.SetnomeDoCliente(obj_Cliente.GetNome());
        locacao.SetmatriculaDoCliente(obj_Cliente.GetMatricula());
        locacao.SetdataDaSaida(tempo.DiaAtual());
        locacao.SetdataDoRetorno(raw_input("\nDATA DO RETORNO DO VEICULO: "));
        locacao.SetdiasDeLocacao(tempo.Datas(locacao.GetdataDaSaida(),locacao.GetdataDoRetorno()));
        locacao.SetvalorASerPago(float(locacao.GetdiasDeLocacao()) * float(obj_Veiculo.GetDiariaDaLocacao()));
        locacao.Setativo("ativa");
        return locacao
                                  
      
    def devolucaoDeVeiculo(self):
        print"DEVOLUCAO DE VEICULO";
        placa = raw_input("\nPLACA DO VEICULO LOCADO: ");
        lista_locacao=self.carregar_lista_arquivo("locacao.tab")
        auxiliar=self.existe_locacao(placa,lista_locacao)
        if auxiliar == True:
            obj_Locacao = self.detalhar_locacao(placa)    
            if obj_Locacao.Getativo() == "ativa": 
                self.mostrar_locacao(placa)
                obj_Veiculo   = self.detalhar_veiculo(placa)
                obj_Veiculo = self.nova_Quilometragem(obj_Veiculo)
                obj_Locacao.Setativo("inativa");
                obj_Veiculo.SetAtivo("ativo");                                
                self.atualizar_arquivo_veiculo(obj_Veiculo,placa)
                self.atualizar_arquivo_locacao(obj_Locacao,placa)
                while 1:
                    multa = raw_input("\nO VEICULO LOCADO RECEBEU ALGUMA MULTA[1-SIM 2-NAO]: ");
                    if multa=="1":
                        self.cadastrar_multa(obj_Veiculo,obj_Locacao)
                        print "MULTA CADASTRADA COM SUCESSO."
                        break
                    if multa=="2":
                        break
                print "\nLOCACAO DEVOLVIDA COM SUCESSO"
            else:
                print " Esta Placa nao possui locacao ativa."
        else:
            print " Esta Placa nao possui locacao ativa."

    def detalhar_locacao(self,placa):
        obj_Locacao = Locacao();
        lista_locacao=self.carregar_lista_arquivo("locacao.tab")
        obj_Locacao.SetplacaDoVeiculo(placa)
        #FAZ O DETALHAMENTO DA LOCACAO PESQUISADA.
        for p,i in enumerate(lista_locacao):
            if i.GetplacaDoVeiculo()==obj_Locacao.GetplacaDoVeiculo():
                obj_Locacao.SetplacaDoVeiculo(i.GetplacaDoVeiculo()),
                obj_Locacao.Setativo(i.Getativo()),
                obj_Locacao.SetordemDeLocacao(i.GetordemDeLocacao()),
                obj_Locacao.SetnomeDoVendedor(i.GetnomeDoVendedor()),
                obj_Locacao.SetnomeDoCliente(i.GetnomeDoCliente()),
                obj_Locacao.SetmatriculaDoCliente(i.GetmatriculaDoCliente()), 
                obj_Locacao.SetdataDaSaida(i.GetdataDaSaida()),
                obj_Locacao.SetdataDoRetorno(i.GetdataDoRetorno()),
                obj_Locacao.SetdiasDeLocacao(i.GetdiasDeLocacao()),
                obj_Locacao.SetvalorASerPago(i.GetvalorASerPago()), 
                return obj_Locacao



    def mostrar_locacao(self,placa):
        obj_Locacao = Locacao();
        lista_locacao=self.carregar_lista_arquivo("locacao.tab")
        obj_Locacao.SetplacaDoVeiculo(placa)
        #FAZ O DETALHAMENTO DA LOCACAO PESQUISADA.
        for p,i in enumerate(lista_locacao):
            if i.GetplacaDoVeiculo()==obj_Locacao.GetplacaDoVeiculo():
                print"==========================================";
                print"LOCACAO ENCONTRADA:";
                print"ORDEM DE LOCACAO: " + str(i.GetordemDeLocacao());
                print"PLACA DO VEICULO: " + str(i.GetplacaDoVeiculo());
                print"NOME DO VENDEDOR: " + str(i.GetnomeDoVendedor());
                print"NOME DO CLIENTE: " + str(i.GetnomeDoCliente());
                print"MATRICULA DO CLIENTE: " + str(i.GetmatriculaDoCliente());
                print"DATA DE SAIDA: " + str(i.GetdataDaSaida());
                print"DATA DE RETORNO: " + str(i.GetdataDoRetorno());
                print"DIAS DE LOCACAO: " + str(i.GetdiasDeLocacao());
                valor=raw_input("VALOR A SER PAGO: " + str(i.GetvalorASerPago()))
                print"==========================================";        

    
    def atualizar_arquivo_veiculo(self,obj,placa):
        lista_veiculos=self.carregar_lista_arquivo("veiculo.tab")
        #ATUALIZA O ARQUIVO VEICULO.
        for p,i in enumerate(lista_veiculos):
            if i.GetPlaca()==placa:
                del lista_veiculos[p]
                lista_veiculos.append(obj)        
                self.descarregar_lista_arquivo("veiculo.tab",lista_veiculos)
        
    def atualizar_arquivo_locacao(self,obj,placa):
        lista_locacao=self.carregar_lista_arquivo("locacao.tab")
        #ATUALIZA O ARQUIVO LOCACAO.
        for p,i in enumerate(lista_locacao):
            if i.GetplacaDoVeiculo()==placa:
                del lista_locacao[p]
        lista_locacao.append(obj)
        self.descarregar_lista_arquivo("locacao.tab",lista_locacao)

    
    def nova_Quilometragem(self,obj):
        obj_Veiculo = obj
        print "ANTIGA KM DO VEICULO" , str(obj_Veiculo.GetKm())
        obj_Veiculo.SetKm(raw_input("\nNOVO KM DO VEICULO: "));    
        return obj_Veiculo

    def mostrar_carros_disp(self):
        obj_Veiculo = Veiculo();
        lista_veiculos=self.carregar_lista_arquivo("veiculo.tab")
        print"\nPLACA    MODELO       KM_ATUAL    KM_DE_MANUTENCAO"
        # PRINTAR VEICULOS DISPONIVEIS.
        for p,i in enumerate(lista_veiculos):
            if i.GetAtivo()=="ativo":
                print "",i.GetPlaca(),"   ",i.GetModelo(),"      ",i.GetKm(),"        ",i.GetKmDeManutencao()

    def mostrar_clientes_cadastrados(self):
        obj_Cliente = Cliente();
        lista_clientes=self.carregar_lista_arquivo("cliente.tab")
        print"\nNome dos Clientes Cadastrados:"
        # PRINTAR CLIENTES CADASTRADOS.
        for p,i in enumerate(lista_clientes):            
                print i.GetNome()                

    def voltar_ao_Menu(self):
        voltar=raw_input("Aperte [ enter ] para voltar ao menu")
                    

    def menuInicial(self):
        cmd = "15";
        while cmd!="0":
            os.system("cls");
            print "****************************";
            print "SISTEMA LOCADORA DE VEICULOS";
            print "****************************";
            print "[1 + ENTER] PARA CADASTRAR CLIENTE";
            print "[2 + ENTER] PARA DESCADASTRAR CLIENTE";
            print "[3 + ENTER] PARA CADASTRAR VEICULO";
            print "[4 + ENTER] PARA DESCADASTRAR VEICULO";
            print "[5 + ENTER] PARA RETIRAR MULTA";
            print "[6 + ENTER] PARA ABRIR UMA LOCACAO";
            print "[7 + ENTER] PARA REGISTRAR ENTREGA DE VEICULO";
            print "[8 + ENTER] PARA MOSTRAR CLIENTES CADASTRADOS";
            print "[9 + ENTER] PARA MOSTRAR CARROS DISPONIVEIS";
            print "[0 + ENTER] PARA SAIR DO SISTEMA";
            cmd = raw_input("COMANDO: ");
            return cmd            
    


